<template>
  <div class="app-container">
    <el-row :gutter="20">
      <!-- 预测模型配置面板 -->
      <el-col :span="24">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>环境质量预测模型</span>
          </div>
          <el-form :model="queryParams" ref="queryForm" :inline="true">
            <el-form-item label="预测类型" prop="predictionType">
              <el-select clearable v-model="queryParams.predictionType" placeholder="请选择预测类型" @change="handlePredictionTypeChange" >
                <el-option label="空气质量预测" value="A" />
                <el-option label="水质预测" value="W" />
                <el-option label="噪声预测" value="N" />
              </el-select>
            </el-form-item>

            <el-form-item label="监测点" prop="pointId">
              <el-select clearable v-model="queryParams.pointId" placeholder="请选择监测点">
                <el-option
                  v-for="item in monitoringPoints"
                  :key="item.pointId"
                  :label="item.pointName"
                  :value="item.pointId"
                />
              </el-select>
            </el-form-item>

            <el-form-item label="预测指标" prop="indicatorName" v-if="queryParams.predictionType !== 'N'">
              <el-select clearable v-model="queryParams.indicatorName" placeholder="请选择预测指标">
                <el-option
                  v-for="item in indicatorOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>

            <el-form-item label="预测天数" prop="days">
              <el-input-number v-model="queryParams.days" :min="1" :max="30" :step="1" />
            </el-form-item>

            <el-form-item>
              <el-button type="primary" icon="el-icon-search" @click="handleGenerate">生成预测</el-button>
              <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" style="margin-top: 20px;" v-if="predictionId">
      <!-- 预测结果展示面板 -->
      <el-col :span="24">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>预测结果 - {{ predictionInfo.indicatorName }} ({{ predictionInfo.indicatorUnit }})</span>
            <div style="float: right;">
              <span>模型: {{ predictionInfo.modelType }} | 精度: {{ (predictionInfo.modelAccuracy * 100).toFixed(2) }}%</span>
            </div>
          </div>

          <div class="model-info" v-if="predictionInfo.pointName">
            <p><strong>监测点:</strong> {{ predictionInfo.pointName }} | <strong>公园:</strong> {{ predictionInfo.parkName }}</p>
            <p><strong>预测时间范围:</strong> {{ predictionTimeRange }}</p>
          </div>

          <div class="chart-container" v-loading="chartLoading">
            <div id="predictionChart" class="chart"></div>
          </div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="20" style="margin-top: 20px;">
      <!-- 历史预测记录 -->
      <el-col :span="24">
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <span>历史预测记录</span>
          </div>

          <el-table v-loading="loading" :data="predictionList" style="width: 100%;" border>
            <el-table-column label="ID" align="center" prop="predictionId" width="80" />
            <el-table-column label="监测点" align="center" prop="pointName"/>
            <el-table-column label="公园" align="center" prop="parkName"/>
            <el-table-column label="预测类型" align="center" prop="predictionType">
              <template slot-scope="scope">
                <el-tag type="success" v-if="scope.row.predictionType === 'A'">空气质量</el-tag>
                <el-tag type="primary" v-else-if="scope.row.predictionType === 'W'">水质</el-tag>
                <el-tag type="warning" v-else-if="scope.row.predictionType === 'N'">噪声</el-tag>
                <el-tag v-else>未知</el-tag>
              </template>
            </el-table-column>
            <el-table-column label="指标名称" align="center" prop="indicatorName"/>
            <el-table-column label="预测开始时间" align="center" prop="predictionStartTime"/>
            <el-table-column label="预测结束时间" align="center" prop="predictionEndTime"/>
            <el-table-column label="模型类型" align="center" prop="modelType"/>
            <el-table-column label="模型精度" align="center" prop="modelAccuracy">
              <template slot-scope="scope">
                {{ (scope.row.modelAccuracy * 100).toFixed(2) }}%
              </template>
            </el-table-column>
            <el-table-column label="操作" align="center" width="200">
              <template slot-scope="scope">
                <el-button size="mini" type="text" icon="el-icon-view" @click="handleViewPrediction(scope.row)">查看</el-button>
                <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>

          <pagination
            v-show="total > 0"
            :total="total"
            :page.sync="queryParams.pageNum"
            :limit.sync="queryParams.pageSize"
            @pagination="getList"
          />
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import { listPrediction, getPrediction, delPrediction, generateAirQualityPrediction, generateWaterQualityPrediction, generateNoisePrediction, getPredictionTrendData } from '@/api/system/prediction';
import { getAirMonitoringPoints } from '@/api/system/airquality';
import { getNoiseMonitoringPoints } from '@/api/system/noise';
import { getWaterMonitoringPoints } from '@/api/system/waterquality';
import * as echarts from 'echarts';

export default {
  name: 'EnvPrediction',
  data() {
    return {
      // 遮罩层
      loading: false,
      // 图表加载状态
      chartLoading: false,
      // 总条数
      total: 0,
      // 预测列表
      predictionList: [],
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        predictionType: 'A', // 默认空气质量预测
        pointId: null,
        indicatorName: 'aqi', // 默认AQI指标
        days: 7 // 默认预测7天
      },
      // 监测点列表
      monitoringPoints: [],
      // 指标选项
      indicatorOptions: [],
      // 空气质量指标选项
      airIndicatorOptions: [
        { label: 'AQI', value: 'aqi' },
        { label: 'PM2.5', value: 'pm25' },
        { label: 'PM10', value: 'pm10' },
        { label: 'SO2', value: 'so2' },
        { label: 'NO2', value: 'no2' },
        { label: 'CO', value: 'co' },
        { label: 'O3', value: 'o3' }
      ],
      // 水质指标选项
      waterIndicatorOptions: [
        { label: 'pH值', value: 'ph' },
        { label: '溶解氧', value: 'do' },
        { label: '浊度', value: 'turbidity' }
      ],
      // 预测ID
      predictionId: null,
      // 预测信息
      predictionInfo: {},
      // 预测图表实例
      chart: null
    };
  },
  computed: {
    // 预测时间范围
    predictionTimeRange() {
      if (this.predictionInfo.timeList && this.predictionInfo.timeList.length > 0) {
        return `${this.predictionInfo.timeList[0]} 至 ${this.predictionInfo.timeList[this.predictionInfo.timeList.length - 1]}`;
      }
      return '';
    }
  },
  created() {
    this.getList();
    this.handlePredictionTypeChange();
  },
  mounted() {
    // 监听窗口大小变化，调整图表大小
    window.addEventListener('resize', this.resizeChart);
  },
  beforeDestroy() {
    // 销毁图表实例
    if (this.chart) {
      this.chart.dispose();
      this.chart = null;
    }

    // 移除窗口大小变化监听
    window.removeEventListener('resize', this.resizeChart);
  },
  methods: {
    /** 查询预测列表 */
    getList() {
      this.loading = true;
      listPrediction(this.queryParams).then(response => {
        this.predictionList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },

    /** 处理预测类型变化 */
    handlePredictionTypeChange() {
      // 根据预测类型加载对应的监测点和指标选项
      switch (this.queryParams.predictionType) {
        case 'A': // 空气质量
          this.getAirMonitoringPoints();
          this.indicatorOptions = this.airIndicatorOptions;
          this.queryParams.indicatorName = 'aqi';
          break;
        case 'W': // 水质
          this.getWaterMonitoringPoints();
          this.indicatorOptions = this.waterIndicatorOptions;
          this.queryParams.indicatorName = 'ph';
          break;
        case 'N': // 噪声
          this.getNoiseMonitoringPoints();
          this.indicatorOptions = [];
          this.queryParams.indicatorName = null;
          break;
      }
    },

    /** 获取空气质量监测点 */
    getAirMonitoringPoints() {
      getAirMonitoringPoints().then(response => {
        this.monitoringPoints = response.data;
        if (this.monitoringPoints.length > 0) {
          this.queryParams.pointId = this.monitoringPoints[0].pointId;
        }
      });
    },

    /** 获取水质监测点 */
    getWaterMonitoringPoints() {
      // 直接调用水质监测点API
      getWaterMonitoringPoints().then(response => {
        this.monitoringPoints = response.data;
        if (this.monitoringPoints.length > 0) {
          this.queryParams.pointId = this.monitoringPoints[0].pointId;
        }
      });
    },

    /** 获取噪声监测点 */
    getNoiseMonitoringPoints() {
      getNoiseMonitoringPoints().then(response => {
        this.monitoringPoints = response.data;
        if (this.monitoringPoints.length > 0) {
          this.queryParams.pointId = this.monitoringPoints[0].pointId;
        }
      });
    },

    /** 重置查询参数 */
    resetQuery() {
      this.resetForm("queryForm");
      this.queryParams.predictionType = 'A';
      this.queryParams.days = 7;
      this.handlePredictionTypeChange();
    },

    /** 生成预测 */
    handleGenerate() {
      if (!this.queryParams.pointId) {
        this.$message.warning('请选择监测点');
        return;
      }

      if (this.queryParams.predictionType !== 'N' && !this.queryParams.indicatorName) {
        this.$message.warning('请选择预测指标');
        return;
      }

      this.chartLoading = true;

      // 根据预测类型调用不同的预测API
      let generatePromise;
      switch (this.queryParams.predictionType) {
        case 'A': // 空气质量
          generatePromise = generateAirQualityPrediction(
            this.queryParams.pointId,
            this.queryParams.indicatorName,
            this.queryParams.days
          );
          break;
        case 'W': // 水质
          generatePromise = generateWaterQualityPrediction(
            this.queryParams.pointId,
            this.queryParams.indicatorName,
            this.queryParams.days
          );
          break;
        case 'N': // 噪声
          generatePromise = generateNoisePrediction(
            this.queryParams.pointId,
            this.queryParams.days
          );
          break;
      }

      generatePromise.then(response => {
        if (response.code === 200) {
          this.$message.success('预测数据生成成功');
          this.predictionId = response.data.predictionId;
          this.getList(); // 刷新列表
          this.getPredictionTrendData(this.predictionId);
        } else {
          this.$message.error(response.msg || '预测数据生成失败');
          this.chartLoading = false;
        }
      }).catch(() => {
        this.chartLoading = false;
      });
    },

    /** 获取预测趋势数据 */
    getPredictionTrendData(predictionId) {
      this.chartLoading = true;
      getPredictionTrendData(predictionId).then(response => {
        if (response.code === 200) {
          this.predictionInfo = response.data;
          this.initChart();
        } else {
          this.$message.error(response.msg || '获取预测趋势数据失败');
        }
        this.chartLoading = false;
      }).catch(() => {
        this.chartLoading = false;
      });
    },

    /** 初始化图表 */
    initChart() {
      // 如果已有图表实例，先销毁
      if (this.chart) {
        this.chart.dispose();
      }

      // 创建图表实例
      this.chart = echarts.init(document.getElementById('predictionChart'));

      // 设置图表选项
      const option = {
        title: {
          text: `${this.predictionInfo.indicatorName}预测趋势`,
          left: 'center'
        },
        tooltip: {
          trigger: 'axis',
          formatter: (params) => {
            const param = params[0];
            return `${param.axisValue}<br/>${param.seriesName}: ${param.value} ${this.predictionInfo.indicatorUnit}`;
          }
        },
        xAxis: {
          type: 'category',
          data: this.predictionInfo.timeList,
          axisLabel: {
            rotate: 45,
            formatter: (value) => {
              // 只显示日期和小时
              return value.substring(5, 16);
            }
          }
        },
        yAxis: {
          type: 'value',
          name: this.predictionInfo.indicatorName + (this.predictionInfo.indicatorUnit ? ` (${this.predictionInfo.indicatorUnit})` : '')
        },
        series: [{
          name: this.predictionInfo.indicatorName,
          type: 'line',
          data: this.predictionInfo.valueList,
          smooth: true,
          markPoint: {
            data: [
              { type: 'max', name: '最大值' },
              { type: 'min', name: '最小值' }
            ]
          },
          markLine: {
            data: [
              { type: 'average', name: '平均值' }
            ]
          },
          itemStyle: {
            color: this.getColorByPredictionType(this.queryParams.predictionType)
          },
          lineStyle: {
            width: 3
          },
          areaStyle: {
            opacity: 0.3,
            color: this.getColorByPredictionType(this.queryParams.predictionType, true)
          }
        }]
      };

      // 设置图表选项
      this.chart.setOption(option);
    },

    /** 调整图表大小 */
    resizeChart() {
      if (this.chart) {
        this.chart.resize();
      }
    },

    /** 根据预测类型获取颜色 */
    getColorByPredictionType(type, isGradient = false) {
      let color;
      switch (type) {
        case 'A': // 空气质量
          color = '#67C23A';
          break;
        case 'W': // 水质
          color = '#409EFF';
          break;
        case 'N': // 噪声
          color = '#E6A23C';
          break;
        default:
          color = '#67C23A';
      }

      if (isGradient) {
        return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: color },
          { offset: 1, color: 'rgba(255, 255, 255, 0.3)' }
        ]);
      }

      return color;
    },

    /** 查看预测详情 */
    handleViewPrediction(row) {
      this.predictionId = row.predictionId;
      this.getPredictionTrendData(row.predictionId);
    },

    /** 删除预测记录 */
    handleDelete(row) {
      const predictionId = row.predictionId;
      this.$modal.confirm('是否确认删除预测记录编号为"' + predictionId + '"的数据项?').then(function() {
        return delPrediction(predictionId);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
        // 如果删除的是当前正在查看的预测，清空预测ID
        if (this.predictionId === predictionId) {
          this.predictionId = null;
        }
      }).catch(() => {});
    }
  }
};
</script>

<style scoped>
.app-container .el-card {
  margin-bottom: 20px;
}

.chart-container {
  width: 100%;
  height: 400px;
}

.chart {
  width: 100%;
  height: 100%;
}

.model-info {
  margin-bottom: 20px;
  padding: 10px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.indicator-select {
  margin-bottom: 20px;
}
</style>
